#include "IrTransmit.h"

// 保存外部传入的 TIM 句柄（例如 TIM2）
static TIM_HandleTypeDef *htim_ir = NULL;

// ================= 底层载波控制 =================

// 开启 PWM 输出（38kHz 载波）
static void IR_Transmit_StartCarrier(void)
{
    HAL_TIM_PWM_Start(htim_ir, TIM_CHANNEL_2);
}

// 关闭 PWM 输出（低电平）
static void IR_Transmit_StopCarrier(void)
{
    HAL_TIM_PWM_Stop(htim_ir, TIM_CHANNEL_2);
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET); // 确保为低电平
}

// NEC 协议：发送载波一段时间
void NEC_Mark(uint32_t time_us)
{
    IR_Transmit_StartCarrier();
    DWT_Delay_us(time_us);
    IR_Transmit_StopCarrier();
}

// NEC 协议：保持低电平一段时间
void NEC_Space(uint32_t time_us)
{
    IR_Transmit_StopCarrier();
    if (time_us > 0)
        DWT_Delay_us(time_us);
}

// ================= 上层接口 =================

void IrTransmit_Init(TIM_HandleTypeDef *htim)
{
    htim_ir = htim;
    DWT_Delay_Init();
    // ⚠️ TIM2_CH2 已在 CubeMX / HAL_Init 中配置成 38kHz PWM
}

// 发送一个完整的 NEC 帧
void IrTransmit_SendFrame(const NECFrame *frame)
{
    // 1. 发送引导码
    NEC_Mark(NEC_HEADER_PULSE);
    NEC_Space(NEC_HEADER_SPACE);

    // 2. 按字节 LSB first 发送
    if (frame->mode == NEC_STANDARD)
    {
        uint8_t bytes[4] = {
            (uint8_t)(frame->address & 0xFF),
            (uint8_t)(~frame->address & 0xFF),
            frame->command,
            (uint8_t)(~frame->command)};
        for (int b = 0; b < 4; b++)
        {
            for (int i = 0; i < 8; i++) // LSB first
            {
                NEC_Mark(NEC_BIT_MARK);
                if (bytes[b] & (1 << i))
                    NEC_Space(NEC_ONE_SPACE);
                else
                    NEC_Space(NEC_ZERO_SPACE);
            }
        }
    }
    else if (frame->mode == NEC_EXTENDED)
    {
        uint8_t bytes[4] = {
            (uint8_t)(frame->address & 0xFF),        // 地址低字节
            (uint8_t)((frame->address >> 8) & 0xFF), // 地址高字节
            frame->command,
            (uint8_t)(~frame->command)};
        for (int b = 0; b < 4; b++)
        {
            for (int i = 0; i < 8; i++)
            {
                NEC_Mark(NEC_BIT_MARK);
                if (bytes[b] & (1 << i))
                    NEC_Space(NEC_ONE_SPACE);
                else
                    NEC_Space(NEC_ZERO_SPACE);
            }
        }
    }

    // 3. 结束位
    NEC_Mark(NEC_BIT_MARK);
    NEC_Space(0);
}
